package com.busdepot.imc;

import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.springframework.stereotype.Service;

import com.imcparts.IMCCatalogLeasingServices;
import com.imcparts.IMCCatalogLeasingServicesPortType;
import com.imcparts.schema.CategoryInformationType;
import com.imcparts.schema.LimitedProductInformationType;
import com.imcparts.schema.LineInformationType;
import com.imcparts.schema.ProductInformationType;
import com.imcparts.schema.VehicleInformationType;

@Service
public class ImcServiceImpl implements ImcService {

	private static final String ACCOUNT_NUMBER = "444449";
	private static final String API_VERSION_ID = "20060912";

	private IMCCatalogLeasingServicesPortType port;
	
	public ImcServiceImpl() {
		QName serviceName = new QName("http://www.imcparts.com", "IMC-CatalogLeasingServices");
		URL wsdlUrl = getClass().getResource("/imc.wsdl");
		IMCCatalogLeasingServices catalogLeasingService = new IMCCatalogLeasingServices(wsdlUrl, serviceName);
		port = catalogLeasingService.getCatalogServices();
		configureAuthentication(port);
	}

	public List<CategoryInformationType> getCategoryInformation(List<String> vid) {
		return port.getCategoryInformation(API_VERSION_ID, ACCOUNT_NUMBER, vid);
	}

	public List<LineInformationType> getLineInformation(List<String> vid, List<String> category) {
		return port.getLineInformation(API_VERSION_ID, ACCOUNT_NUMBER, vid, category);
	}

	public List<String> getMakeInformation() {
		return port.getMakeInformation(API_VERSION_ID, ACCOUNT_NUMBER);
	}

	public List<ProductInformationType> getProductInformation(List<String> vid, List<String> line) {
		return port.getProductInformation(API_VERSION_ID, ACCOUNT_NUMBER, vid, line);
	}

	public List<VehicleInformationType> getVehicleInformation(String make, String year) {
		return port.getVehicleInformation(API_VERSION_ID, ACCOUNT_NUMBER, make, year);
	}

	public List<LineInformationType> keywordSearch(String keyword, List<String> vid) {
		return port.keywordSearch(API_VERSION_ID, ACCOUNT_NUMBER, keyword, vid);
	}

	public List<LimitedProductInformationType> partNumberSearch(List<String> partNumber) {
		return port.partNumberSearch(API_VERSION_ID, ACCOUNT_NUMBER, partNumber);
	}

	private void configureAuthentication(IMCCatalogLeasingServicesPortType port) {
		
		Client client = org.apache.cxf.frontend.ClientProxy.getClient(port);
		Endpoint cxfEndpoint = client.getEndpoint();

		Map<String, Object> outProps = new HashMap<String, Object>();
		outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
		outProps.put(WSHandlerConstants.USER, "busdepottest");
		// Password type : plain text
		outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
		outProps.put(WSHandlerConstants.MUST_UNDERSTAND, "false");

		// for hashed password use:
		// outProps.put(WSHandlerConstants.PASSWORD_TYPE,
		// WSConstants.PW_DIGEST);

		outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordHandler.class.getName());

		WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
		cxfEndpoint.getOutInterceptors().add(wssOut);
	}
}
